
#include "main.h"
#include "mir3da.h"


/**
 * @brief this function is used to get the acc value
 * 			note: the acc value is 14bit with sign
 * @param x 			acc value of x
 * @param y 			acc value of y
 * @param z 			acc value of z
 * @return char 
 */


char mir3da_read_data(signed short *x, signed short *y, signed short *z)
{
	unsigned char    tmp_data[6] = {0};

	mir3da_register_read(NSA_REG_ACC_X_MSB, &tmp_data[0], 1);	
	mir3da_register_read(NSA_REG_ACC_X_LSB, &tmp_data[1], 1);

	mir3da_register_read(NSA_REG_ACC_Y_MSB, &tmp_data[2], 1);
	mir3da_register_read(NSA_REG_ACC_Y_LSB, &tmp_data[3], 1);

	mir3da_register_read(NSA_REG_ACC_Z_MSB, &tmp_data[4], 1);
	mir3da_register_read(NSA_REG_ACC_Z_LSB, &tmp_data[5], 1);

	*x = (tmp_data[0] << 4) | (tmp_data[1] >> 4);	
	*y = (tmp_data[2] << 4) | (tmp_data[3] >> 4);
	*z = (tmp_data[4] << 4) | (tmp_data[5] >> 4);

	if (*x & 0x800)
	{
		*x |= 0xF000;
	}

	if (*y & 0x800)
	{
		*y |= 0xF000;
	}

	if (*z & 0x800)
	{
		*z |= 0xF000;
	}
	

	return 0;
}

/**
 * @brief this function is used to get the acc value
 * 			note: the x axis acc value is 14bit with sign, but the y and z axis acc value is 8bit with sign
 * @param x 			acc value of x
 * @param y 			acc value of y
 * @param z 			acc value of z
 * @return char 
 */

void mir3da_read_data_char(signed short *x, signed char *y, signed char *z)
{
	unsigned char    tmp_data[2] = {0};

	mir3da_register_read(NSA_REG_ACC_X_MSB, &tmp_data[0], 1);
	mir3da_register_read(NSA_REG_ACC_X_LSB, &tmp_data[1], 1);

	*x = (tmp_data[0] << 4) | (tmp_data[1] >> 4);

	mir3da_register_read(NSA_REG_ACC_Y_MSB, &tmp_data[0], 1);
	mir3da_register_read(NSA_REG_ACC_Z_MSB, &tmp_data[1], 1);

	*y = (signed char)tmp_data[0];
	*z = (signed char)tmp_data[1];

}



char mir3da_register_read(unsigned char addr, unsigned char *data_m, unsigned char len)
{
	// To do i2c read api
	//   AD228_read(addr,data_m);

	IIC_Start();
	IIC_SendByte(0x4e);
	IIC_WaitAck();
	IIC_SendByte(addr);
	IIC_WaitAck();
	IIC_Stop();

	IIC_Delay(DELAY_TIME);

	IIC_Start();
	IIC_SendByte(0x4f);
	IIC_WaitAck();

	IIC_Delay(DELAY_TIME);

	*data_m = IIC_RecByte();
	IIC_WaitAck();
	IIC_Stop();

	return 0;
}

void AD228_read(unsigned char addr, unsigned char *data_m)
{
	IIC_Start();
	IIC_SendByte(0x4e);
	IIC_WaitAck();
	IIC_SendByte(addr);
	IIC_WaitAck();
	IIC_Stop();

	IIC_Delay(DELAY_TIME);

	IIC_Start();
	IIC_SendByte(0x4f);
	IIC_WaitAck();

	IIC_Delay(DELAY_TIME);

	*data_m = IIC_RecByte();
	IIC_WaitAck();
	IIC_Stop();
}

char mir3da_register_write(unsigned char addr, unsigned char data_m)
{
	// To do i2c write api
	//   AD228_write(addr,data_m);

	IIC_Start();
	IIC_SendByte(0x4e);
	IIC_WaitAck();
	IIC_SendByte(addr);
	IIC_WaitAck();
	IIC_SendByte(data_m);
	IIC_WaitAck();
	IIC_Stop();

	return 0;
}

void AD228_write(unsigned char addr, unsigned char dat)
{
	IIC_Start();
	IIC_SendByte(0x4e);
	IIC_WaitAck();
	IIC_SendByte(addr);
	IIC_WaitAck();
	IIC_SendByte(dat);
	IIC_WaitAck();
	IIC_Stop();
}



char mir3da_set_enable(unsigned char enable)
{
	char res = 0;
	if (enable)
		// res = mir3da_register_write(NSA_REG_POWERMODE_BW,0x14);
		res = mir3da_register_write(NSA_REG_POWERMODE_BW, 0x4c);
	else
		// res = mir3da_register_write(NSA_REG_POWERMODE_BW,0x80);
		res = mir3da_register_write(NSA_REG_POWERMODE_BW, 0x4c);
	return res;
}

char mir3da_init(void)
{
	char res = 0;
	unsigned char data_m = 0;

	while (data_m != 0x13)
	{
		mir3da_register_write(0x00, 0x24); // soft reset
		DelayMs(50);

		res = mir3da_register_read(NSA_REG_WHO_AM_I, &data_m, 1);
		DelayMs(10);
	}

	// printf("------mir3da chip id = %x-----\r\n",data_m);

	/*
		00:2g
		01:4g
	*/
	res |= mir3da_register_write(NSA_REG_G_RANGE, 0x00); //+/-4G,14bit
	/*
		0x34��ʾ����ģʽ��500HZ
		0x46��ʾ�͹���ģʽ��3.9HZ
		0x06��ʾ����ģʽ��3.9HZ
	*/
	res |= mir3da_register_write(NSA_REG_POWERMODE_BW, 0x34); // normal mode
	// res |= mir3da_register_write(NSA_REG_ODR_AXIS_DISABLE, 0x07);      //ODR = 125hz
	/*
		 0x05��ʾ31.25Hz
		 0x00��ʾ1HZ
	*/
	res |= mir3da_register_write(NSA_REG_ODR_AXIS_DISABLE, 0x05);

	/*��INT������Ϊ��������ߵ�ƽ**/
	res |= mir3da_register_write(NSA_REG_INT_PIN_CONFIG, 0x01);
	// res |= mir3da_register_write(NSA_REG_INT_PIN_CONFIG, 0x00);

	// Engineering mode
	res |= mir3da_register_write(NSA_REG_ENGINEERING_MODE, 0x83);
	res |= mir3da_register_write(NSA_REG_ENGINEERING_MODE, 0x69);
	res |= mir3da_register_write(NSA_REG_ENGINEERING_MODE, 0xBD);

	// Reduce power consumption
	//  if(i2c_addr == 0x26){
	//  	mir3da_register_mask_write(NSA_REG_SENS_COMP, 0x40, 0x00);
	//  }
#if 0
	mir3da_register_mask_write(0x8f, 0x02, 0x00);
#endif
	return res;
}

// open active interrupt
signed char mir3da_open_interrupt(unsigned char th)
{
	signed char res = 0;

	/*�������2+1ms������ֵ�������ж�*/
	res = mir3da_register_write(NSA_REG_ACTIVE_DURATION, 0x02);

	/*�����ж���ֵactive_th*K(mg)��K = 7.81(4g range)*/
	res |= mir3da_register_write(NSA_REG_ACTIVE_THRESHOLD, th);

	/*����ж�ӳ�䵽INT*/
	res |= mir3da_register_write(NSA_REG_INTERRUPT_MAPPING1, 0x04);

	/*����100ms*/
	res |= mir3da_register_write(NSA_REG_INT_LATCH, 0xEE); // latch 100ms

	/*����xyz��ж�*/
	res |= mir3da_register_write(NSA_REG_INTERRUPT_SETTINGS1, 0x87);

	return res;
}

// close active interrupt
signed char mir3da_close_interrupt(void)
{
	signed char res = 0;

	res = mir3da_register_write(NSA_REG_INTERRUPT_SETTINGS1, 0x00);
	res = mir3da_register_write(NSA_REG_INTERRUPT_MAPPING1, 0x00);

	return res;
}

void IIC_Delay(unsigned char i)
{
	unsigned a = 0;
	for (a = 0; a < i; a++)
		;
}

// #define SCL_OUTPUT TRISB0=0
// #define SDA_OUTPUT TRISB1=0
// #define SCL_INPUT TRISB0=1
// #define SDA_INPUT TRISB1=1

// I2C???????????
void IIC_Start(void)
{
	SDA_OUTPUT;
	SDA = 1;
	SCL = 1;
	IIC_Delay(DELAY_TIME);
	SDA = 0;
	IIC_Delay(DELAY_TIME);
	SCL = 0;
}

// I2C?????????
void IIC_Stop(void)
{
	SDA_OUTPUT;
	SDA = 0;
	SCL = 1;
	IIC_Delay(DELAY_TIME);
	SDA = 1;
	IIC_Delay(DELAY_TIME);
}

//??????
unsigned char IIC_WaitAck(void)
{
	static unsigned char ackbit;

	IIC_Delay(DELAY_TIME);
	SCL = 1;

	SDA_INPUT;
	IIC_Delay(DELAY_TIME);
	ackbit = SDA;
	SCL = 0;
	SDA_OUTPUT;
	IIC_Delay(DELAY_TIME);
	return ackbit;
}

// I2C?????????????????
void IIC_SendByte(unsigned char byt)
{
	unsigned char i;

	// SDA_OUTPUT;

	for (i = 0; i < 8; i++)
	{
		SCL = 0;
		IIC_Delay(DELAY_TIME);
		if (byt & 0x80)
			SDA = 1;
		else
			SDA = 0;
		IIC_Delay(DELAY_TIME);
		SCL = 1;
		byt <<= 1;
		IIC_Delay(DELAY_TIME);
	}
	SCL = 0;
}

// I2C?????????????????
unsigned char IIC_RecByte(void)
{
	unsigned char i;
	unsigned char d = 0;

	for (i = 0; i < 8; i++)
	{
		SCL = 1;
		SDA_INPUT;
		IIC_Delay(DELAY_TIME);
		d <<= 1;
		if (SDA)
			d |= 1;
		SCL = 0;
		IIC_Delay(DELAY_TIME);
	}
	return d;
}
